package interfaces

import (
	"deploy/interfaces/db"
	"deploy/schema"
	"deploy/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	"io"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strconv"
)

// 日志文件上传
func (s *Server)LogUpload(c *gin.Context) {
	result := schema.Result{}
	defer func() {
		if err := recover(); err != nil {
			if result.Code==0{
				result.Code = 400
			}
			result.Err = fmt.Sprintf("%s",err)
		}
		c.JSON(result.Code,result)
	}()
	// 上传的参数校验
	file, header, err := c.Request.FormFile("filename")
	if err != nil{
		panic("上传文件的参数错误")
	}
	// log.Printf("%v",header)
	filename := header.Filename
	hostname := c.Query("hostname")
	md5 := c.Query("md5")
	log.Printf("agent :%s 上传日志：%s ~~~",hostname,filename)
	// 创建临时接收文件
	basePath := "./files/log/"+hostname+"/"
	if !utils.DirExist(basePath){
		os.Mkdir(basePath,0755)
		log.Printf("创建目录%s成功\n",basePath)
	}
	newfilename := md5+"-"+filename
	baseFile := basePath + filepath.Base(newfilename)
	if utils.FileExist(baseFile){
		log.Println("上传相同文件: "+newfilename+"!")
	}
	// 计算md5
	out, err := os.Create(baseFile)
	if err != nil {
		panic(err)
	}
	defer out.Close()
	// Copy数据
	_, err = io.Copy(out, file)
	if err != nil {
		panic(err)
	}
	url := path.Join(s.Conf.FileServer.Log,hostname,newfilename)
	err=s.Db.UpdateLogByFilename(newfilename, hostname,map[string]interface{}{"status":"处理完成","file_name":newfilename,"url":url,"md5":md5})
	if err!=nil{
		log.Println("上传日志时更新日志状态异常：",err.Error())
	}
	result.Msg="文件上传成功"
	result.Data=gin.H{"url":url,"md5":md5}
	result.Code=http.StatusOK
}


//  查看上传过的日志列表信息 时间倒序
func (s *Server)GetLogGet(c *gin.Context) {
	result := schema.Result{}
	defer func() {
		if err := recover(); err != nil {
			if result.Code==0{
				result.Code = 400
			}
			result.Err = fmt.Sprintf("%s",err)
		}
		c.JSON(result.Code,result)
	}()
	// 上传的参数校验
	pageSize := c.Query("page_size")
	pageNum := c.Query("page_num")
	ps,err:=strconv.Atoi(pageSize)
	if err != nil{
		log.Println("JobStatusDetail 查询服务器部署详情异常：",err)
		result.Code=400
		panic("page_size参数异常")
	}
	pn,err := strconv.Atoi(pageNum)
	if err != nil{
		log.Println("JobStatusDetail 查询服务器部署详情异常：",err)
		result.Code=400
		panic("page_num参数异常")
	}
	// 查库
	logs := []db.UploadLog{}
	err =s.Db.PageGetLog(ps,pn,&logs)
	if err !=nil{
		panic("查询数据库异常")
	}
	// 数据加工处理
	data := []map[string]interface{}{}
	for _,i := range logs{
		a := map[string]interface{}{
			"url":i.Url,
			"file_name":i.FileName,
			"last_mod_time":i.LastModTime,
			"hostname":i.Hostname,
			"status":i.Status,
			"description":i.Description,
		}
		data = append(data, a)
	}
	result.Code=200
	result.Msg="数据查询成功"
	result.Data=data
	// 返回
}

//  用户通过这个接口 向agent发起任务 让它上传日志
func (s *Server)PostGetLog(c *gin.Context){
	// 返回处理
	result := schema.Result{}
	defer func() {
		if err := recover(); err != nil {
			if result.Code==0{
				result.Code = 400
			}
			result.Err = fmt.Sprintf("%s",err)
		}
		c.JSON(result.Code,result)
	}()
	//参数格式检验
	req := schema.PostGetLogSchema{}
	err := c.BindJSON(&req)
	if err != nil {
		log.Println(err.Error())
		panic("参数错误")
	}
	// 通过主机名参数 找到这个client
	client :=s.FindAClientByNameFromServer(req.Hostname)
	log.Println(client)
	if client == nil{
		panic("服务器不在线")
	}
	// 向agent发送请求
	m:=utils.StrMessage{
		Str: req.Filename,
	}
	msg :=utils.NewMessage("12345678",9,utils.ToJson(&m))
	client.outChan<-msg
	// 等结果
	clientResult:=<-client.SyncChan
	cr,ok := clientResult.(utils.UploadFileInfoMessage)
	if ok{
		log.Println("收到agent返回数据：",cr)
		if cr.Md5 != "" && cr.Name !=""{
			// 查看是否有相同的文件
			//写入数据库
			_,filename :=path.Split(req.Filename)
			saveFilename := fmt.Sprintf("%s-%s",cr.Md5,filename)
			obj:=db.UploadLog{}
			err = s.Db.GetLogByFilename(saveFilename,&obj)
			if err !=nil{
				log.Println("查询库中是否已上传文件时异常：",err.Error())
			}
			if obj.ID>0{
				result.Code=400
				result.Msg="此文件已经从服务器上传过，重复操作"
				return
			}

			uploadlog := db.UploadLog{
				FileName:    	saveFilename,
				LastModTime:	cr.ModTime,
				Hostname:   	req.Hostname,
				Status:     	"上传中",
				Md5:         	cr.Md5,
				Description:	req.Description,
			}
			err = s.Db.NewUploadLog(&uploadlog)
			if err !=nil{
				log.Printf("用户发起日志上传请求 hostname:%s filename: %s 时，写入数据库失败:%v\n",req.Hostname,req.Filename,err.Error())
				result.Code=500
				result.Msg="服务器内部错误"
				return
			}
			result.Code=200
			result.Data=map[string]interface{}{
				"file_name":saveFilename,
			}
			result.Msg="上传中请稍候"
		}else{
			result.Code=404
			panic("文件异常")
		}
	}else{
		log.Printf("用户发起日志上传请求 hostname:%s filename: %s 时，写入数据库失败:%v\n",req.Hostname,req.Filename,err.Error())
		result.Code=500
		result.Msg="服务器内部错误"
		return
	}

}

//  UI通过这个接口向server发送 查看目录里有哪些文件
func (s *Server)PostListDir(c *gin.Context) {
	// 返回处理
	result := schema.Result{}
	defer func() {
		if err := recover(); err != nil {
			if result.Code==0{
				result.Code = 400
			}
			result.Err = fmt.Sprintf("%s",err)
		}
		c.JSON(result.Code,result)
	}()
	req := schema.PostListDirSchema{}
	err := c.BindJSON(&req)
	if err != nil {
		log.Println(err.Error())
		panic("参数错误")
	}

	// 通过主机名参数 找到这个client
	client :=s.FindAClientByNameFromServer(req.Hostname)
	log.Println(client)
	if client == nil{
		panic("主机异常")
	}
	// 向agent发送请求
	m:=utils.StrMessage{
		Str: req.Dir,
	}
	msg :=utils.NewMessage("12345678",8,utils.ToJson(&m))
	client.outChan<-msg
	// 等结果
	clientResult:=<-client.SyncChan
	// 看到结果 写入数据库
	cr,ok := clientResult.(utils.FileListMessage)
	if ok{
		if len(cr.FileList)>0{
			result.Msg="查看日志列表成功"
		}else{
			result.Msg="目录为空或目录异常"
		}

	}else{
		log.Println("日志转换数据格式失败")
		panic("查看日志列表失败")
	}
	result.Data=cr
	// 返回结果 给ui
}

//  用户通过这个接口 向agent发起任务 让它上传日志
func (s *Server)GetLogByTime(c *gin.Context){
	// 返回处理
	result := schema.Result{}
	defer func() {
		if err := recover(); err != nil {
			if result.Code==0{
				result.Code = 400
			}
			result.Err = fmt.Sprintf("%s",err)
		}
		c.JSON(result.Code,result)
	}()
	//参数格式检验
	req := schema.GetLogByTimeSchema{}
	err := c.BindJSON(&req)
	if err != nil {
		log.Println(err.Error())
		panic("参数错误")
	}
	// 通过主机名参数 找到这个client
	client :=s.FindAClientByNameFromServer(req.Hostname)
	log.Println(client)
	if client == nil{
		panic("服务器不在线")
	}
	// 添加服务数据
	data,_ := utils.GetDataConfiguration(req.ServerName)
	//formatTimeStr:="2017-04-11 13:33:37"
	log.Println(data)
	req.LogHead=data.LogHead
	req.LogDir=data.LogDir
	msg :=utils.NewMessage("12345678",11,utils.ToJson(&req))
	client.outChan<-msg
	// 等结果
	clientResult:=<-client.SyncChan
	cr,ok := clientResult.(utils.UploadFileInfoMessage)

	if ok{
		log.Println("收到agent返回数据：",cr)
		if cr.Md5 != "" && cr.Name !=""{
			// 查看是否有相同的文件
			//写入数据库
			fm:=path.Base(cr.Name)
			saveFilename := fmt.Sprintf("%s-%s",cr.Md5,fm)
			obj:=db.UploadLog{}
			err = s.Db.GetLogByFilename(saveFilename,&obj)
			if err !=nil{
				log.Println("查询库中是否已上传文件时异常：",err.Error())
			}
			if obj.ID>0{
				result.Code=400
				result.Msg="此文件已经从服务器上传过，重复操作"
				return
			}

			uploadlog := db.UploadLog{
				FileName:    saveFilename,
				LastModTime: cr.ModTime,
				Hostname:    req.Hostname,
				Status:      "处理中",
				Md5:         cr.Md5,
				Description: req.Description,
			}
			err = s.Db.NewUploadLog(&uploadlog)
			if err !=nil{
				log.Printf("用户发起日志上传请求 hostname:%s filename: %s 时，写入数据库失败:%v\n",req.Hostname,cr.Name,err.Error())
				result.Code=500
				result.Msg="服务器内部错误"
				return
			}
			result.Code=200
			result.Data=map[string]interface{}{
				"file_name":saveFilename,
			}
			result.Msg="处理中请稍候"
		}else{
			result.Code=404
			panic("文件异常")
		}
	}else{
		log.Printf("用户发起日志上传请求 hostname:%s filename: %s 时，写入数据库失败:%v\n",req.Hostname,cr.Name,err.Error())
		result.Code=500
		result.Msg="服务器内部错误"
		return
	}

}